package com.fts.fts.fitness_tracking_system.controller;

import cn.hutool.crypto.digest.MD5;
import com.fts.fts.fitness_tracking_system.pojo.EmailRequest;
import com.fts.fts.fitness_tracking_system.pojo.Users;
import com.fts.fts.fitness_tracking_system.service.impl.SysBaseApiImpl;
import com.fts.fts.fitness_tracking_system.service.impl.UsersServiceImpl;
import com.fts.fts.fitness_tracking_system.utils.JwtUtil;
import com.fts.fts.fitness_tracking_system.utils.Result;
import com.fts.fts.fitness_tracking_system.utils.VerificationCodeUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.UUID;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UsersServiceImpl usersService;
    @Autowired
    private SysBaseApiImpl sysBaseApi;

    @Value("${avatar.upload-dir}")
    private String uploadDir;

    @Value("${avatar.access-url}")
    private String accessUrlPrefix;


    @PostMapping("/login")
    public Result<?> userLogin(@RequestBody Users user) {
        Users users = usersService.userLogin(user.getUsername(), user.getPassword());
        if (users != null) {
            String token = JwtUtil.generateToken(user.getUsername(), users.getUserId());
            return new Result<>(200, "登录成功", token);
        }
        return new Result<>(400, "登录失败");
    }

    @PostMapping("/register")
    public Result<?> registerUser(@RequestBody Users user) {
        // 检查用户名是否已存在
        Users existingUser = usersService.checkUser(user.getEmail());
        if (existingUser != null) {
            return new Result<>(400, "用户名已存在");
        }

        // 加密密码并保存用户
        user.setPassword(MD5.create().digestHex(user.getPassword()));
        usersService.userRegister(user);
        return new Result<>(200, "注册成功");
    }

    @GetMapping("/info")
    public Result<?> getUserInfo(@RequestHeader(value = "Authorization", defaultValue = "") String token, HttpServletRequest request) {
        // 打印所有 Headers
        System.out.println("===== Headers Start =====");
        java.util.Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String headerName = headerNames.nextElement();
            String headerValue = request.getHeader(headerName);
            System.out.println(headerName + ": " + headerValue);
        }
        System.out.println("===== Headers End =====");

        if (token.equals("")) {
            return new Result<>(401, "未授权");
        }
        boolean validate = JwtUtil.validateToken(token);
        if (!validate) {
            return new Result<>(401, "未授权");
        }
        Claims claims = JwtUtil.parseToken(token);
        Integer userId = (Integer) claims.get("userId");
        Users user = usersService.getUserInfo(userId);
        if (user == null) {
            return new Result<>(400, "用户不存在");
        }
        return new Result<>(200, "获取成功", user);
    }

    @GetMapping("/isExist")
    public Result<?> isExist(@RequestParam String email) {
        Users user = usersService.getUserInfoByEmail(email);
        if (user == null) {
            return new Result<>(200, "用户不存在", false);
        }
        return new Result<>(200, "获取成功", true);
    }

    @PostMapping("/update")
    public Result<?> updateUser(@RequestBody Users user) {
        try {
            usersService.updateUser(user);
        } catch (Exception e) {
            return new Result<>(400, "更新失败");
        }
        return new Result<>(200, "更新成功");
    }

    @PostMapping("/updatePassword")
    public Result<?> updatePassword(@RequestHeader(value = "Authorization") String token, @RequestBody String newPassword) {
        if (token.equals("")) {
            return new Result<>(401, "未授权");
        }
        boolean validate = JwtUtil.validateToken(token);
        if (!validate) {
            return new Result<>(401, "未授权");
        }
        Claims claims = JwtUtil.parseToken(token);
        Integer userId = (Integer) claims.get("userId");
        try {
            usersService.updatePassword(userId, newPassword);
        } catch (IllegalArgumentException e) {
            // 捕获密码相同的异常，并返回特定提示
            return new Result<>(400, e.getMessage());
        } catch (Exception e) {
            // 其他异常返回通用错误信息
            return new Result<>(400, "更新失败");
        }
        return new Result<>(200, "更新成功");
    }

    // 发送验证码
    @PostMapping("/sendCode")
    public Result<?> sendVerificationCode(@RequestBody EmailRequest param) {
        String code = VerificationCodeUtil.generateCode();
        sysBaseApi.sendVerificationCode(param.getEmail(), code);
        sysBaseApi.saveCode(param.getEmail(), code);
        return new Result<>(200, "验证码已发送");
    }

    // 验证验证码
    @PostMapping("/verifyCode")
    public Result<?> verifyCode(@RequestBody EmailRequest param) {
        String storedCode = sysBaseApi.getCode(param.getEmail());
        if (storedCode == null) {
            return new Result<>(400, "验证码已过期");
        }
        if (!storedCode.equals(param.getCode())) {
            return new Result<>(400, "验证码错误");
        }
        // 验证成功后删除验证码
        sysBaseApi.deleteCode(param.getEmail());
        return new Result<>(200, "验证成功");
    }

    @PostMapping("/updatePasswordByEmail")
    public Result<?> updatePasswordByEmail(@RequestBody EmailRequest param) {
        Users user = usersService.getUserInfoByEmail(param.getEmail());
        if (user == null) {
            return new Result<>(400, "用户不存在");
        }
        try {
            usersService.updatePassword(user.getUserId(), param.getNewPassword());
        } catch (IllegalArgumentException e) {
            // 捕获密码相同的异常，并返回特定提示
            return new Result<>(400, e.getMessage());
        } catch (Exception e) {
            // 其他异常返回通用错误信息
            return new Result<>(400, "更新失败");
        }
        return new Result<>(200, "更新成功");
    }


    @PostMapping("/avatar")
    public Result<?> uploadAvatar(
            @RequestParam("files") MultipartFile[] files,
            @RequestHeader("Authorization") String token) {

        try {
            // 1. Token验证
            Integer userId = null;
            if (!JwtUtil.validateToken(token)) {
                boolean validate = JwtUtil.validateToken(token);
                if (!validate) {
                    return new Result<>(401, "未授权");
                }
                Claims claims = JwtUtil.parseToken(token);
                userId = (Integer) claims.get("userId");
            }

            MultipartFile file = files[0];
            // 2. 生成唯一文件名
            String originalFilename = file.getOriginalFilename();
            String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
            String newFilename = UUID.randomUUID() + fileExtension;

            // 3. 保存文件
            Path uploadPath = Paths.get(uploadDir);
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
            }
            Path filePath = uploadPath.resolve(newFilename);
            Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING);

            // 4. 保存路径到数据库
            String accessUrl = accessUrlPrefix + newFilename;
//            Users user = usersService.getUserInfo(userId);
//            if (user == null) {
//                return new Result<>(400, "用户不存在");
//            }
//            user.setAvatar(accessUrl);
//            usersService.updateUser(user);

            return new Result<>(200, "上传成功", accessUrl);
        } catch (IOException e) {
            return new Result<>(400, "文件存储失败");
        }
    }


}
